package controller

import (
	_ "database/sql"
	"fmt"
	"os/exec"
	"strconv"
	"strings"
	"sync"
	"time"

	"gitee.com/goshark/dhs/model"

	"gitee.com/johng/gf/g/encoding/gjson"
	"gitee.com/johng/gf/g/frame/gmvc"
	"gitee.com/johng/gf/g/net/ghttp"
)

type ControllerBackup struct {
	gmvc.Controller
}

type TaskBackupContent struct {
	Ip           string   `json:"ip,omitempty"`
	Dbuser       string   `json:"dbuser,omitempty"`
	Dbpass       string   `json:"dbpass,omitempty"`
	Dbport       int      `json:"dbport,omitempty"`
	BackFileName string   `json:"backFileName,omitempty"`
	Dababases    []string `json:"dababases,omitempty"`
}

type ErrorRepoting struct {
	Error_info string `json:"error_info,omitempty"` //错误详情
	Task_info  *Task  `json:"task_info,omitempty"`  //任务详情
}

// 初始化控制器对象，并绑定操作到Web Server
func init() {
	ghttp.GetServer().BindController("/backup", new(ControllerBackup))
}

//实例化表
func (bak *ControllerBackup) M(tables string) *model.Models {
	return model.NewDB(tables)
}

func (bak *ControllerBackup) Exec() {
	bak.Response.WriteJson(&Response{Success: 0, Msg: "操作成功,任务已启动"})
	remoteaddr := strings.Split(bak.Request.RemoteAddr, ":")[0] //获取调用方ip
	task := new(Task)
	task_backup := new(TaskBackupContent)
	nowtime := time.Now().Unix()
	params_b, _ := GetParams(bak).ToJson()
	gjson.DecodeTo(params_b, &task)                            //解析请求数据到task结构
	task_backup_b, _ := gjson.New(task.Content.Value).ToJson() //将任务内容的value字段编码
	gjson.DecodeTo(task_backup_b, &task_backup)                //解析到备份结构

	if task.Starttime > 0 && task.Starttime > nowtime {
		time.Sleep(time.Duration((task.Starttime - nowtime)) * time.Second) //开始时间-当前时间 = 段时间,阻塞一段时间
	}
	//根据task_backup.BackFileName结合时间动态生成备份文件名称
	task_backup.BackFileName = time.Now().Format("2006_01_02_15_04_05") + ".sql"
	time_now := time.Now()
	td, err := time.ParseDuration(task.Interval)
	if err != nil {
		fmt.Println("转换错误", err.Error())
	}
	fmt.Println("line68程序执行时间******", time.Now().Format("2006年01月02号15点04分05秒"))
	fmt.Println("task结构", task)
	fmt.Println("task_backup结构", task_backup)
	fmt.Println("duration转换值", td)
	var wg sync.WaitGroup
	for i := 0; i < task.Repeatcount; i++ {
		//程序体...

		if time.Now().After(time_now.Add(td)) || i == 0 {
			time_now = time.Now() //刷新现在的时间
			wg.Add(1)
			go func() {
				fmt.Println("line80程序执行时间******", time.Now().Format("2006年01月02号15点04分05秒"))
				c := "mysqldump -hlocalhost -u" + task_backup.Dbuser + " -p" + task_backup.Dbpass + " -P" + strconv.Itoa(task_backup.Dbport) + " -d " + strings.Join(task_backup.Dababases, " ") + " > " + task_backup.BackFileName
				fmt.Println(c)
				cmd0 := exec.Command("sh", "-c", c)

				err := cmd0.Start()

				if err != nil {
					fmt.Println("line85行执行出错", err.Error())
					errrepoting_b, _ := gjson.New(&ErrorRepoting{Error_info: err.Error(), Task_info: task}).ToJson()
					ghttp.NewClient().Post("http://"+remoteaddr+":8888/task/errorepoting", ghttp.BuildParams(map[string]string{
						"jsoninfo": string(errrepoting_b),
					}))

					wg.Done()
					return
				}
				err = cmd0.Wait()
				if err != nil {
					fmt.Println("line96行执行出错", err.Error())
					errrepoting_b, _ := gjson.New(&ErrorRepoting{Error_info: err.Error(), Task_info: task}).ToJson()
					ghttp.NewClient().Post("http://"+remoteaddr+":8888/task/errorepoting", ghttp.BuildParams(map[string]string{
						"jsoninfo": string(errrepoting_b),
					}))
					wg.Done()
					return
				}

				wg.Done()

			}()
			wg.Wait()

		}

	}

	if task.Repeatcount == 0 {

		for {
			//程序体...

			wg.Add(1)
			go func() {

				if time.Now().After(time_now.Add(td)) {
					time_now = time.Now() //刷新现在的时间
					c := "mysqldump -hlocalhost -u" + task_backup.Dbuser + " -p" + task_backup.Dbpass + " -P" + strconv.Itoa(task_backup.Dbport) + " -d " + strings.Join(task_backup.Dababases, " ") + " > " + task_backup.BackFileName
					fmt.Println(c)
					cmd0 := exec.Command("sh", "-c", c)
					err := cmd0.Start()

					if err != nil {
						fmt.Println("line128行执行出错", err.Error())
						errrepoting_b, _ := gjson.New(&ErrorRepoting{Error_info: err.Error(), Task_info: task}).ToJson()
						ghttp.NewClient().Post("http://"+remoteaddr+":8888/task/errorepoting", ghttp.BuildParams(map[string]string{
							"jsoninfo": string(errrepoting_b),
						}))
						wg.Done()
						return
					}
					err = cmd0.Wait()
					if err != nil {
						fmt.Println("line138行执行出错", err.Error())
						errrepoting_b, _ := gjson.New(&ErrorRepoting{Error_info: err.Error(), Task_info: task}).ToJson()
						ghttp.NewClient().Post("http://"+remoteaddr+":8888/task/errorepoting", ghttp.BuildParams(map[string]string{
							"jsoninfo": string(errrepoting_b),
						}))
						wg.Done()
						return
					}

				}

				wg.Done()

			}()

			wg.Wait()

		}
	}

}
